package com.unionftech.content_login.service

import android.content.Context
import android.os.CancellationSignal
import androidx.credentials.ClearCredentialStateRequest
import androidx.credentials.CredentialManager
import androidx.credentials.CredentialManagerCallback
import androidx.credentials.CustomCredential
import androidx.credentials.GetCredentialRequest
import androidx.credentials.GetCredentialResponse
import androidx.credentials.exceptions.ClearCredentialException
import androidx.credentials.exceptions.GetCredentialException
import com.google.android.libraries.identity.googleid.GetSignInWithGoogleOption
import com.google.android.libraries.identity.googleid.GoogleIdTokenCredential
import com.unionftech.common.utils.LogUtils
import java.util.concurrent.ExecutorService
import java.util.concurrent.Executors

object GoogleCredentialManagerSign {
    private const val TAG = "GoogleCredentialManagerSign"
    private const val WEB_CLIENT_ID = LoginConstants.Constant.GOOGLE_LOGIN_WEB_CLIENT_ID
    private lateinit var credentialManager: CredentialManager
    private lateinit var executor: ExecutorService

    /**
     * Google登录
     */
    @JvmStatic
    fun googleLogin(context: Context, callBack: (idToken: String) -> Unit) {
        //使用 触发“使用 Google 登录”按钮流的方式进行Google登录
        val googleIdOption: GetSignInWithGoogleOption =
            GetSignInWithGoogleOption
                .Builder(WEB_CLIENT_ID)
                .build()
        val request = GetCredentialRequest.Builder()
            .addCredentialOption(googleIdOption)
            .build()

        val cancellationSignal = CancellationSignal()
        cancellationSignal.setOnCancelListener {
            LogUtils.d(TAG, "用户取消Google登录")
        }
        if (!::credentialManager.isInitialized) {
            credentialManager = CredentialManager.create(context)
        }
        if (!::executor.isInitialized) {
            executor = Executors.newSingleThreadExecutor()
        }
        credentialManager.getCredentialAsync(context,
            request,
            cancellationSignal,
            executor,
            object : CredentialManagerCallback<GetCredentialResponse, GetCredentialException> {
                override fun onError(e: GetCredentialException) {
                    handleFailure(e)
                }

                override fun onResult(result: GetCredentialResponse) {
                    handleSignIn(result, callBack)
                }
            })

    }

    /**
     * Google注销
     */
    @JvmStatic
    fun googleLogout() {
        val clearCredentialStateRequest = ClearCredentialStateRequest()
        val cancellationSignal = CancellationSignal()
        cancellationSignal.setOnCancelListener {
            LogUtils.d(TAG, "用户取消Google注销")
        }
        if (::credentialManager.isInitialized) {
            credentialManager.clearCredentialStateAsync(clearCredentialStateRequest,
                cancellationSignal,
                executor,
                object : CredentialManagerCallback<Void?, ClearCredentialException> {
                    override fun onError(e: ClearCredentialException) {
                        LogUtils.e(TAG, "Google注销登录失败")
                    }

                    override fun onResult(result: Void?) {
                        LogUtils.d(TAG, "Google注销登录成功")
                    }
                })
        }

    }

    private fun handleSignIn(result: GetCredentialResponse, callBack: (idToken: String) -> Unit) {
        when (val credential = result.credential) {
            is CustomCredential -> {
                if (GoogleIdTokenCredential.TYPE_GOOGLE_ID_TOKEN_CREDENTIAL == credential.type) {
                    val googleIdTokenCredential =
                        GoogleIdTokenCredential.createFrom(credential.data)
                    val id = googleIdTokenCredential.id
                    val name = googleIdTokenCredential.displayName
                    val familyName = googleIdTokenCredential.familyName
                    val givenName = googleIdTokenCredential.givenName
                    val phoneNumber = googleIdTokenCredential.phoneNumber
                    val photo = googleIdTokenCredential.profilePictureUri
                    val idToken = googleIdTokenCredential.idToken
                    LogUtils.d(
                        TAG,
                        "handleSignIn--->GoogleIdTokenCredential:\n " + " + id: ${id}\n" + " + displayName: ${name}\n" + " + idToken: ${idToken}\n" + " + profilePictureUri: ${photo}\n" + " + givenName: ${givenName}\n" + " + familyName: ${familyName}\n" + "+ phoneNumber: $phoneNumber\n"

                    )
                    // Use googleIdTokenCredential and extract id to validate and
                    // authenticate on your server.
                    callBack.invoke(idToken)
                } else {
                    LogUtils.e(TAG, "handleSignIn--->Unexpected type of credential")
                }
            }

            else -> {
                LogUtils.e(TAG, "handleSignIn--->Unexpected type of credential")
            }
        }
    }

    private fun handleFailure(e: GetCredentialException) {
        e.printStackTrace()
        LogUtils.e(TAG, "handleFailure--->${e.message.toString()}")
    }
}